package com.clh.seckill.filter;

import com.clh.seckill.config.AccessLimit;
import com.clh.seckill.config.UserContext;
import com.clh.seckill.controller.LoginController;
import com.clh.seckill.exception.GlobalException;
import com.clh.seckill.pojo.User;
import com.clh.seckill.service.UserService;
import com.clh.seckill.utils.CookieUtil;
import com.clh.seckill.vo.RespBean;
import com.clh.seckill.vo.RespBeanEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
 * @Author cailinhu
 * @Description 自定义拦截器
 * @Date 2021-10-29 17:41
 * @Version 1.0
 */
@Component
@Slf4j
public class InformationFilter implements HandlerInterceptor {
    @Autowired
    private UserService userService;
    @Autowired
    RedisTemplate redisTemplate;
    /**
     * 预处理回调方法
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //将两大请求对象保存到线程中去
        UserContext.setRequest(request);
        UserContext.setResponse(response);
        String userTick = CookieUtil.getUid(request, "userTick");
        User user = userService.getUserByCookie(userTick, response);
        //通过拦截器+注解做到所有接口限流操作
//        if (handler instanceof HandlerMethod){
//            //只针对方法
//            AccessLimit annotation = ((HandlerMethod) handler).getMethodAnnotation(AccessLimit.class);
//            if (annotation!=null){
//                int second = annotation.second();//多少秒失效
//                int maxCount = annotation.maxCount();//登录次数
//                boolean needLogin= annotation.needLogin();
//                String key = request.getRequestURI();
//                if (needLogin){
//                    if (null==user){
//                        //那就不能过了
//                        render(response,RespBeanEnum.IDENTITY_OUT);
//                        return false;
//                    }
//                    UserContext.setUser(user);
//                    key+=":"+user.getId();
//                }
//                ValueOperations operations = redisTemplate.opsForValue();
//                Integer count = (Integer) operations.get(key);
//                if (count==null)
//                    operations.set(key,maxCount,second, TimeUnit.SECONDS);
//                else if (count<maxCount)
//                    operations.increment(key);
//                else{
//                    render(response,RespBeanEnum.OPERATION_OFTEN);
//                    return false;
//                }
//                return true;
//            }
//        }

        //两套逻辑互不干涉（上面） 上面是只有打了注解的才可以跳过用户拦截
        if (user!=null){
            log.info("人员信息认证成功！登录名为:"+user.getNickname());
            UserContext.setUser(user);
            return true;
        }
        request.setAttribute("identity_out",RespBean.error(RespBeanEnum.IDENTITY_OUT,null));
        request.getRequestDispatcher("/login/index").forward(request,response);
        return false;
    }

    private void render(HttpServletResponse response, RespBeanEnum respBeanEnum) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();
        RespBean error = RespBean.error(respBeanEnum, null);
        String json = new ObjectMapper().writeValueAsString(error);
        out.write(json);
        out.flush();
        out.close();
    }


}
